home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Online / MiamiSDK / examples / ttcptest.c < prev   
Encoding:
C/C++ Source or Header  |  1997-12-04  |  4.2 KB  |  166 lines

  1. /*
  2.  * ttcptest.c
  3.  *
  4.  * Small example for a T/TCP-compliant client.
  5.  *
  6.  * This client tries to connect to the auth (identd) port of the
  7.  * specified host using T/TCP. If T/TCP is not supported it falls
  8.  * back to TCP.
  9.  *
  10.  * (C) Copyright 1996,1997 by Nordic Global Inc. All rights reserved.
  11.  * T/TCP code for use with Miami only.
  12.  *
  13.  * 07/30/97
  14.  */
  15.  
  16. #include <proto/exec.h>
  17. #include <proto/miami.h>
  18. #include <proto/socket.h>
  19.  
  20. #include <sys/socket.h>
  21. #include <netinet/tcp.h>
  22. #include <netdb.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <errno.h>
  27.  
  28.  
  29. struct Library *MiamiBase=0;
  30.  
  31. static int dottcp=0;
  32.  
  33. #define REQUEST "1 : 1\r\n"
  34.  
  35. void get_response(int sockfd,char *buf,int max) {
  36.     int len=0,le;
  37.     while(len<max-1) {
  38.         le=recv(sockfd,buf+len,max-len-1,0);
  39.         if(le==0) {
  40.             buf[len]=0;
  41.             return;
  42.         }
  43.         if(le<0) {
  44.             fprintf(stderr,"recv: error %d\n",Errno());
  45.             exit(10);
  46.         }
  47.         len+=le;
  48.     }
  49.     buf[max-1]=0;
  50. }    
  51.  
  52. void main(int argc,char **argv) {
  53.     struct hostent *he;
  54.     struct servent *se;
  55.     int sockfd,n=1,err;
  56.     char buf[256];
  57.     struct sockaddr_in sin;
  58.  
  59.     if(argc==0)
  60.         exit(0);
  61.     if(argc!=2) {
  62.         fprintf(stderr,"Usage: %s host\n",argv[0]);
  63.         exit(10);
  64.     }
  65.  
  66.  
  67.     /* miami.library versions >= 3 support T/TCP */
  68.  
  69.     if(MiamiBase=OpenLibrary("miami.library",3)) {
  70.         CloseLibrary(MiamiBase);
  71.         dottcp=1;
  72.     }
  73.  
  74.  
  75.     if(!(he=gethostbyname(argv[1]))) {
  76.         fprintf(stderr,"Host not found\n");
  77.         exit(10);
  78.     }
  79.     if(!(se=getservbyname("auth","tcp"))) {
  80.         fprintf(stderr,"Service `auth' not found\n");
  81.         exit(10);
  82.     }
  83.     if(0>(sockfd=socket(PF_INET,SOCK_STREAM,0))) {
  84.         fprintf(stderr,"Unable to create socket\n");
  85.         exit(10);
  86.     }
  87.  
  88.     sin.sin_family=AF_INET;
  89.     sin.sin_len=sizeof(sin);
  90.     memcpy(&sin.sin_addr,he->h_addr,he->h_length);
  91.     sin.sin_port=se->s_port;
  92.  
  93.     /* ---- start of T/TCP stuff */
  94.     if(dottcp) {
  95.  
  96.         /* The following call is useful if a sendto() may be larger than
  97.            the MSS, to ensure that packets are packed tightly. (If this seems
  98.            strange, that's probably because it is. It has to do with some
  99.            odd quirks in the implementation of sosend() in all BSD-derived
  100.            TCP/IP stacks. Don't ask any questions -- just add this call
  101.            to your program :-)).
  102.  
  103.            HOWEVER: only add the call if you do NOT reuse your TCP connection
  104.            for multiple requests. If you want to transmit multiple pairs of
  105.            "transaction"/"response" across the same TCP link (e.g. HTTP 1.1
  106.            "persistent TCP connections"), then do NOT add the following
  107.            call. */
  108.  
  109.         setsockopt(sockfd,IPPROTO_TCP,TCP_NOPUSH,(char *)&n,sizeof(n));
  110.  
  111.         
  112.         /* Instead of the usual connect() followed by send(), for T/TCP you
  113.            use a sendto() call, as you would for UDP sockets.
  114.            
  115.            If you have a known amount of data to send that you can send in
  116.            a single function call, then you should use one single sendto()
  117.            call with the MSG_EOF flag set, as in this example. This is the
  118.            preferred way to do it, and gives best performance.
  119.  
  120.            If you absolutely need to loop then use a sequence like
  121.  
  122.             sendto(,,,0,,);
  123.             while(!done) {
  124.              send(,,,0);
  125.             }
  126.             send(,,,MSG_EOF);
  127.  
  128.            this means set the MSG_EOF flag in the *last* send() call only.
  129.  
  130.            MSG_EOF performs an implicit shutdown() for one direction of the
  131.            link, improving performance because the shutdown() can be
  132.            piggy-backed on data packets, i.e. no additional packets are
  133.            needed for a shutdown() or CloseSocket() later.
  134.            
  135.            However *do not* use MSG_EOF if you want to re-use your
  136.            connection for subsequent requests (e.g. "persistent TCP
  137.            connections" in HTTP-1.1). */
  138.  
  139.         if(sendto(sockfd,REQUEST,strlen(REQUEST),MSG_EOF,(struct sockaddr *)&sin,
  140.          sizeof(sin))!=strlen(REQUEST)) {
  141.             if((err=Errno())==ENOTCONN) {
  142.                  /* T/TCP failed. Try ordinary TCP */
  143.                 dottcp=0;
  144.             } else {
  145.                 fprintf(stderr,"sendto: error %d\n",err);
  146.                 exit(10);
  147.             }
  148.         }
  149.     }
  150.     /* ---- end of T/TCP stuff */
  151.     
  152.     if(!dottcp) {
  153.         if(connect(sockfd,(struct sockaddr *)&sin,sizeof(sin))<0) {
  154.             fprintf(stderr,"connect: error %d\n",Errno());
  155.             exit(10);
  156.         }
  157.         if(send(sockfd,REQUEST,strlen(REQUEST),0)!=strlen(REQUEST)) {
  158.             fprintf(stderr,"send: error %d\n",Errno());
  159.             exit(10);
  160.         }
  161.     }
  162.     get_response(sockfd,buf,256);
  163.     puts(buf);
  164.     CloseSocket(sockfd);
  165. }
  166.